#pragma once

// 定制协议

#include "Common.hpp"
#include <jsoncpp/json/json.h>

const string Sep = "\r\n";

// 给字符串加报头：后面字符串的长度，方便读取完整的报文
// len\r\n{json}\r\n
bool Encode(string& message)
{
    if(message.size() == 0) return false;
    string package = to_string(message.size()) + Sep + message + Sep;  // 报文加上分隔符和报头
    message = package;
    return true;
}

// 给字符串解报头，获取报文
bool Decode(string& package, string* content)
{
    int pos = package.find(Sep);
    if(pos == string::npos) return false;  // 如果没有找到，说明没有一个完整的报文，直接返回false
    string content_length_str = package.substr(0, pos);  // 报头：也就是报文的长度
    int content_length = stoi(content_length_str);
    int full_length = content_length_str.size() + content_length + 2*Sep.size();
    if(package.size() < full_length)
        return false;
    // 输出型参数：获取报文
    *content = package.substr(pos+Sep.size(), content_length);
    // 删除前面使用了的报文和报头，方便后续使用
    package.erase(0, full_length);
    return true;
}

// _x _oper _y  这是一种约定，要这样传参，要这样计算
class Request
{
public:
    Request()
        :_x(0)
        ,_y(0)
        ,_oper(0)
    {}
    Request(int x, int y, int oper)
        :_x(x)
        ,_y(y)
        ,_oper(oper)
    {}

    // 序列化
    bool Serialization(string& out_string)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;
        
        Json::StreamWriterBuilder wb;
        unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        stringstream ss;
        w->write(root, &ss);
        out_string = ss.str();
        return true;
    }

    // 反序列化
    bool deserialization(string& in_string)
    {
        Json::Value root;
        Json::Reader reader;
        bool parsingSuccessful = reader.parse(in_string, root);
        if(!parsingSuccessful)
        {
            cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << endl;
            return false;
        }

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();  // 特殊之处：char类型也当整数处理，因为是可以转ASCII码值的
        return true;
    }

    int X() const{ return _x; }

    int Y() const{ return _y; }
    
    char Oper() const{ return _oper; }

private:
    int _x;  // 左数
    int _y;  // 右数
    char _oper;  // 操作符
};

class Response
{
public:
    Response()
        :_result(0)
        ,_code(0)
    {}
    Response(int result, int code)
        :_result(result)
        ,_code(code)
    {}

    // 序列化
    bool Serialization(string& out_string)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        
        Json::StreamWriterBuilder wb;
        unique_ptr<Json::StreamWriter> w(wb.newStreamWriter());
        stringstream ss;
        w->write(root, &ss);
        out_string = ss.str();
        return true;
    }

    // 反序列化
    bool deserialization(string& in_string)
    {
        Json::Value root;
        Json::Reader reader;
        bool parsingSuccessful = reader.parse(in_string, root);
        if(!parsingSuccessful)
        {
            cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << endl;
            return false;
        }

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        return true;
    }

    int Result() const{ return _result; }

    int Code() const{ return _code; }

    void SetResult(int res) { _result = res; }

    void SetCode(int code) { _code = code; } 

private:
    int _result;  // 计算结果
    int _code;  // 出错码（0，1，2，3...） 这也是一种约定，什么码返回什么
};